package com.adcc.loadsheet.monitor.entity;

import com.adcc.loadsheet.monitor.util.AlarmEnum;
import com.adcc.loadsheet.monitor.util.Constant;
import com.adcc.loadsheet.monitor.util.StringUtil;

import java.util.HashSet;
import java.util.Set;

/**
 * BGS监控信息
 */
public class BGSMonitor extends BaseEntity implements Cloneable{

    // 主机名称
    private String host;

    // 网关名称
    private String name;

    // BGS状态
    private MonitorStatus status = MonitorStatus.ABNORMAL;

    // AGS状态
    private boolean agsStatus;

    // MQ状态
    private boolean mqStatus;

    // 下行报状态
    private MonitorStatus downlinkStatus= MonitorStatus.ABNORMAL;

    // 下行报更新时间
    private String downlinkUpdateTime;

    // 上行报状态
    private MonitorStatus uplinkStatus= MonitorStatus.ABNORMAL;

    // 上行报更新时间
    private String uplinkUpdateTime;

    // 异常状态码(0：正常，1：异常，状态机:00,例如11标识模块监控项均异常)
    private String errorCode = "0000";

    // 异常原因：XXX IS DOWN,XXX IS DOWN
    private String errorReason = "";

    // 本模块异常的节点
    Set<String> alarmContent = new HashSet<>();

    // 本模块正常的节点（用于判断告警确认后，部分节点正常后又异常需要重新告警）
    Set<String> unAlarmContent = new HashSet<>();

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MonitorStatus getStatus() {
        return status;
    }

    public void setStatus(MonitorStatus status) {
        this.status = status;
    }

    public boolean isAgsStatus() {
        return agsStatus;
    }

    public void setAgsStatus(boolean agsStatus) {
        this.agsStatus = agsStatus;
    }

    public boolean isMqStatus() {
        return mqStatus;
    }

    public void setMqStatus(boolean mqStatus) {
        this.mqStatus = mqStatus;
    }

    public MonitorStatus getDownlinkStatus() {
        return downlinkStatus;
    }

    public void setDownlinkStatus(MonitorStatus downlinkStatus) {
        this.downlinkStatus = downlinkStatus;
    }

    public String getDownlinkUpdateTime() {
        return downlinkUpdateTime;
    }

    public void setDownlinkUpdateTime(String downlinkUpdateTime) {
        this.downlinkUpdateTime = downlinkUpdateTime;
    }

    public MonitorStatus getUplinkStatus() {
        return uplinkStatus;
    }

    public void setUplinkStatus(MonitorStatus uplinkStatus) {
        this.uplinkStatus = uplinkStatus;
    }

    public String getUplinkUpdateTime() {
        return uplinkUpdateTime;
    }

    public void setUplinkUpdateTime(String uplinkUpdateTime) {
        this.uplinkUpdateTime = uplinkUpdateTime;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorReason() {
        return errorReason;
    }

    public void setErrorReason(String errorReason) {
        this.errorReason = errorReason;
    }

    public Set<String> getAlarmContent() {
        return alarmContent;
    }

    public void setAlarmContent(Set<String> alarmContent) {
        this.alarmContent = alarmContent;
    }

    public Set<String> getUnAlarmContent() {
        return unAlarmContent;
    }

    public void setUnAlarmContent(Set<String> unAlarmContent) {
        this.unAlarmContent = unAlarmContent;
    }

    @Override
    public String toXML() throws Exception {
        return null;
    }

    @Override
    public String toJSON() throws Exception {
        return null;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        BGSMonitor bgs = new BGSMonitor();
        bgs.setHost(host);
        bgs.setName(name);
        bgs.setStatus(status);
        bgs.setAgsStatus(agsStatus);
        bgs.setMqStatus(mqStatus);
        bgs.setDownlinkStatus(downlinkStatus);
        bgs.setDownlinkUpdateTime(downlinkUpdateTime);
        bgs.setUplinkStatus(uplinkStatus);
        bgs.setUplinkUpdateTime(uplinkUpdateTime);
        bgs.setErrorCode(errorCode);
        bgs.setErrorReason(errorReason);
        bgs.setAlarmContent(alarmContent);
        bgs.setUnAlarmContent(unAlarmContent);
        return bgs;
    }

    /**
     * 异常状态码
     */
    public void buildErrorCode() {
        StringBuilder sb = new StringBuilder();
        char[] states = new char[4];
        states[0] = agsStatus ? '0' : '1';
        states[1] = mqStatus ? '0' : '1';
        states[2] = uplinkStatus == MonitorStatus.NORMAL ? '0' : uplinkStatus == MonitorStatus.ABNORMAL ? '1' : '2';
        states[3] = downlinkStatus == MonitorStatus.NORMAL ? '0' : downlinkStatus == MonitorStatus.ABNORMAL ? '1' : '2';
        for(char c : states){
            sb.append(c);
        }
        this.errorCode = sb.toString();

        // [2024-6-01：张丽娟：增加声音和弹窗告警的功能，系统支持对指定告警项进行声音和弹窗告警忽略的功能: 根据状态码获取正常节点和异常节点信息]
        // 本模块异常的节点
        Set<String> alarmContent = new HashSet<>();
        // 本模块正常的节点（用于判断告警确认后，部分节点正常后又异常需要重新告警）
        Set<String> unAlarmContent = new HashSet<>();
        // 保存到数据库的异常信息
        StringBuilder errorReasonBuilder = new StringBuilder();

        AlarmEnum enumAgs = AlarmEnum.BGS_AGS;
        if (states[0] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumAgs.getMysqlLogName()));
            alarmContent.add(enumAgs.getItem());
        }else{
            unAlarmContent.add(enumAgs.getItem());
        }
        AlarmEnum enumMQ = AlarmEnum.BGS_MQ;
        if (states[1] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumMQ.getMysqlLogName()));
            alarmContent.add(enumMQ.getItem());
        }else{
            unAlarmContent.add(enumMQ.getItem());
        }

        AlarmEnum enumUplink = AlarmEnum.BGS_UPLINK;
        if (states[2] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumUplink.getMysqlLogName()));
            alarmContent.add(enumUplink.getItem());
        } else if (states[2] == '2') {
            errorReasonBuilder.append(String.format(Constant.LOG_WARN, enumUplink.getMysqlLogName()));
            alarmContent.add(enumUplink.getItem());
        } else{
            unAlarmContent.add(enumUplink.getItem());
        }

        AlarmEnum enumDownlink = AlarmEnum.BGS_DOWNLINK;
        if (states[3] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumDownlink.getMysqlLogName()));
            alarmContent.add(enumDownlink.getItem());
        }else if(states[3] == '2'){
            errorReasonBuilder.append(String.format(Constant.LOG_WARN, enumDownlink.getMysqlLogName()));
            alarmContent.add(enumDownlink.getItem());
        }else{
            unAlarmContent.add(enumDownlink.getItem());
        }
        this.alarmContent = alarmContent;
        this.unAlarmContent = unAlarmContent;
        this.errorReason = StringUtil.stringBuilderToString(errorReasonBuilder);
    }

    /**
     * 告警升级，需要重新告警，即由一般变严重
     * （告警降级不需要重新告警，即由严重到一般）
     */
    public static Set<String> getReAlarmContents(MonitorStatus lastBgsUplinkStatus, MonitorStatus lastBgsDownLinkStatus,
                                                 MonitorStatus curBgsUplinkStatus, MonitorStatus curBgsDownLinkStatus) {
        // 告警升级，需要重新告警，即由一般变严重（告警降级不需要重新告警，即由严重到一般）
        Set<String> reAlertContent = new HashSet<>();
        // 上一次为一般告警，本次为严重告警
        if(lastBgsUplinkStatus == MonitorStatus.WARNING && curBgsUplinkStatus == MonitorStatus.ABNORMAL){
            AlarmEnum enumUplink = AlarmEnum.BGS_UPLINK;
            reAlertContent.add(enumUplink.getItem());
        }
        // 上一次为一般告警，本次为严重告警
        if(lastBgsDownLinkStatus == MonitorStatus.WARNING && curBgsDownLinkStatus == MonitorStatus.ABNORMAL){
            AlarmEnum enumDownlink = AlarmEnum.BGS_DOWNLINK;
            reAlertContent.add(enumDownlink.getItem());
        }
        return reAlertContent;
    }
}
